package model

import (
	"echo_client/config"
	"encoding/json"
)

const (
	defaultVersion = "v1.0" // 当前消息默认版本
)

// MessageTyp 消息类型
type MessageTyp uint32

const (
	PingMessage MessageTyp = iota
	PongMessage
	CsMachineMessage
	ScMachineMessage
)

// String .
func (t MessageTyp) String() string {
	switch t {
	case PingMessage:
		return "ping"
	case PongMessage:
		return "pong"
	case CsMachineMessage:
		return "cs机器信息消息"
	case ScMachineMessage:
		return "sc机器信息消息"
	default:
		return "未知消息"
	}
}

// Protobuf 和客户端交互消息二进制
type Protobuf []byte

// ToMessage 转换成可读消息格式
func (p Protobuf) ToMessage() *MessageV1 {
	var msg MessageV1
	err := json.Unmarshal(p, &msg)
	if err != nil {
		return nil
	}
	return &msg
}

// MessageV1 消息体
type MessageV1 struct {
	Typ       MessageTyp  `json:"typ"`       // 消息类型
	Timestamp int64       `json:"timestamp"` // 消息发送时间戳
	Secret    int64       `json:"secret"`    // 密钥(用户确认消息准确性)
	Version   string      `json:"version"`   // 消息版本
	From      string      `json:"from"`      // 发件人
	To        string      `json:"to"`        // 收件人
	Body      interface{} `json:"body"`      // 消息内容
}

// ToProtobuf 转换成二进制格式
func (v *MessageV1) ToProtobuf() Protobuf {
	data, err := json.Marshal(v)
	if err != nil {
		return nil
	}
	return data
}

// NewMessageV1 .
func NewMessageV1(typ MessageTyp, nowMs, secret int64, from, to string, body interface{}) *MessageV1 {
	if from == "" {
		from = config.HostName
	}
	return &MessageV1{
		Typ:       typ,
		Timestamp: nowMs,
		Secret:    secret,
		From:      from,
		To:        to,
		Body:      body,
		Version:   defaultVersion,
	}
}

// NewPingMessage ping消息
func NewPingMessage(from, to string, nowMs int64) *MessageV1 {
	if from == "" {
		from = config.HostName
	}
	return &MessageV1{
		Typ:       PingMessage,
		Timestamp: nowMs,
		From:      from,
		To:        to,
		Version:   defaultVersion,
	}
	// TODO 接入用户模块后需要在消息体指定用户状态
}
